package com.bestow.framework.interceptor;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.Map;
import java.util.Properties;

import com.bestow.common.core.domain.BaseEntity;
import com.bestow.common.utils.SecurityUtils;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.springframework.stereotype.Component;

/**
 * who字段自动填充
 * Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)   拦截执行器的方法
 * ParameterHandler (getParameterObject, setParameters)	拦截参数的处理
 * ResultSetHandler (handleResultSets, handleOutputParameters)	拦截结果集的处理
 * StatementHandler (prepare, parameterize, batch, update, query) 拦截Sql语法构建的处理
 *
 * @author @liliu
 */
@Intercepts({@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})})
@Component
public class HandleWhoInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object[] args = invocation.getArgs();
        MappedStatement mappedStatement = (MappedStatement) args[0];
        //modify by liliu 2022年10月15日 登陆时会会写信息到登录日志表此时SecurityUtils中还获取不到用户信息，会报空指针异常,暂时这样处理
        /*if ("com.bestow.system.mapper.SysUserMapper.updateUser".equals(mappedStatement.getId()) || "com.bestow.system.mapper.SysLogininforMapper.insertLogininfor".equals(mappedStatement.getId())) {
            return invocation.proceed();
        }*/
        Long userId;
        try{
            userId = SecurityUtils.getUserId();
        }catch(Exception e){
            userId = 1L;
        }
        SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
        if (sqlCommandType == SqlCommandType.UPDATE) {
            if (args[1] instanceof BaseEntity) {
                BaseEntity baseEntity = (BaseEntity) args[1];
                baseEntity.setUpdateTime(new Date());
                baseEntity.setUpdateBy(userId);
            }else if(args[1] instanceof Map){
                Map<String,Object> map = (Map<String, Object>) args[1];
                Object object = getFirstOrNull(map);
                if(object instanceof BaseEntity) {
                    BaseEntity baseEntity = (BaseEntity) object;
                    baseEntity.setUpdateTime(new Date());
                    baseEntity.setUpdateBy(userId);
                }
            }
        } else if (sqlCommandType == SqlCommandType.INSERT) {
            if (args[1] instanceof BaseEntity) {
                BaseEntity baseEntity = (BaseEntity) args[1];
                baseEntity.setCreateTime(new Date());
                baseEntity.setCreateBy(userId);
            }
        }

        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
    }

    /**
     * 获取第一个key的值
     *
     * @param map
     * @return
     */
    private static Object getFirstOrNull(Map<String, Object> map) {
        Object obj = null;
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            obj = entry.getValue();
            if (obj != null) {
                break;
            }
        }
        return obj;
    }
}
